//
//  SRPacket.m
//  sr01sdkProject
//
//  Created by Linktop on 2022/5/7.
//

#import "SRPacket.h"
#import "SRHistoryData.h"
#import "SDKTool.h"
#import "SRHistoryDataSR03.h"

const uint8_t CMD_HEAD = 0XFE;  // 命令包头
const uint8_t DATA_PKG_SIZE = 20; //字节
const uint8_t INDEX_PKG_HEAD = 0; //第一字节
const uint8_t INDEX_CRC = DATA_PKG_SIZE - 1;

@implementation SRPacket
{
    NSUInteger _historyCount;
}

/// 获取心率血氧数据
/// @param isOpen 开关
+(NSData *)packGetOxygenHrvBoth:(BOOL)both IsOpen:(BOOL)isOpen
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_GET_OXYGEN_HRV;
    
    // 开关
    bytes[2] = isOpen;
    
    if (both) {
        bytes[3] = 0X01; // 1=心率血氧全开
    }
    
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}


/// 关机
+(NSData *)packShutDown
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_SHUT_DOWN;
    
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

/// 关机
+(NSData *)packReboot
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_REBOOT;
    
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

//PACK_CMD_BATTERY
/// 关机
+(NSData *)packBattery
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_BATTERY;
    
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)packGetSteps
{
    
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_GET_STEPS;
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)packGetTemperature
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_GET_TEMPERATURE;

    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)PackReset
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_FACTORY_RESET;
    
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

// 下发获取设备信息5
+(NSData *)PackGetDevInfoFive
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_FUNCTIN_GET_DEVICEINFO_5;
    
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

// 下发设置测量时长 单位 秒 8-180s
+(NSData *)PackSetHrMeasureDuration:(NSInteger)seconds
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_FUNCTIN_SET_HR_MEASURE_DURATION;
    
    if (seconds < 8) {
        seconds = 8;
    }
    
    if (seconds > 180) {
        seconds = 180;
    }
    
    bytes[2] = seconds & 0xFF;
    
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}


+(NSData *)packSN {
    
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_SN;
    
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)packDevInfo {
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_DEVICE_INFO;
    
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
    
}
//实时测量参数设置
+(NSData *)packSettingReralMeasure:(uint8_t)sampleRate IswaveOn:(BOOL)isWaveOn
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_SETTING_SPO_HR_REALTIMEMEASURE;
    if (sampleRate < 50) {
        sampleRate = 50;
    }
    // 采样率
    bytes[2] = sampleRate;
    
    // 波形开关
    bytes[3] = isWaveOn;

    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
    
}

+(NSData *)packSoprtMode:(BOOL)start
           ValueINterval:(uint16_t)valInterval
                Duration:(uint16_t)durationMIn
               SportType:(SDKSportType)spType
{
    uint8_t bytes[20] = {0};
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_SPORT_MODE;
    
    bytes[2] = start;
    
    *((uint16_t *)(bytes + 3)) = valInterval; // 取值间隔
    
    *((uint16_t *)(bytes + 5)) = durationMIn; // 持续时间

    *((uint16_t *)(bytes + 7)) = spType & 0XFF; // 运动类型

    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    return  [NSData dataWithBytes:bytes length:20];
}


+(NSData *)packTimeSync {
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_SYNC_TIME;
    
    NSDate *date = [NSDate date];
    
    // 时间戳
    *((uint32_t *)(bytes + 2)) = (uint32_t)([date timeIntervalSince1970]);
    
//    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSCalendar *calendar  = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; //使用公历 避免用户设置的日历影响设备算时间

    NSDateComponents *components = [calendar components:NSUIntegerMax fromDate:date];
    *((uint16_t *)(bytes + 6)) = (uint16_t)(components.year);
    bytes[8] = (uint8_t)(components.month);
    bytes[9] = (uint8_t)(components.day);
    bytes[10] = (uint8_t)(components.hour);
    bytes[11] = (uint8_t)(components.minute);
    bytes[12] = (uint8_t)(components.second);
    
    
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
    
}

+(NSData *)packHistoryCount {
    
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_HIS_COUNT;
    
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)packBindDevice:(BOOL)bind
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_BIND;
    
    bytes[2] = bind ? 1 : 0 ;
    
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
    
}

/// 开始厂家验证
+(NSData *)packStartAes
{
    uint8_t bytes[20] = {0};
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_START_MANUFACT_CER;
    
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

/// 下发解密原文
+(NSData *)packSendR2:(NSData *)r2
{
    uint8_t bytes[20] = {0};
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_MANUFACT_SEND_R2;
    
    uint8_t * r2Bytes = (uint8_t *)[r2 bytes];
    
    memcpy(bytes+2, (void *)(r2Bytes), r2.length);
    
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    NSData *cmdData =  [NSData dataWithBytes:bytes length:20];
    return cmdData;
}




+(NSData *)packSOSSettingDoubleTapTimes:(uint8_t)doubleTapTimes
                                       SingleTapInterval:(uint8_t)singleTapInterval TapDetectionThreshold:(uint8_t)tapDetectionThreshold
           DoubleTapEffectStartTime:(uint8_t)doubleTapEffectStartTime DoubleTapEffectEndTime:(uint8_t)doubleTapEffectEndTime Open:(BOOL)sosOpen
{
    
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_SOS_SETTING;
    
    bytes[2] = sosOpen ? 1 : 0; // sos 开关
    
    if (doubleTapTimes < 1) {
        doubleTapTimes = 1;
    }else if (doubleTapTimes > 10) {
        doubleTapTimes = 10;
    }
    
    bytes[3] = doubleTapTimes;
    
    bytes[4] = singleTapInterval; //两次单击间隔
    if (tapDetectionThreshold > 63) {
        tapDetectionThreshold = 63;
    }
    bytes[5] = tapDetectionThreshold;
    if (doubleTapEffectEndTime <= doubleTapEffectStartTime) {
        doubleTapEffectEndTime = doubleTapEffectStartTime + 1;
    }
    bytes[6] = doubleTapEffectStartTime;
    bytes[7] = doubleTapEffectEndTime;
    
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
    
}
///
/// - Parameters:
///   - on: 开关
///   - sampleRate: 采样率 默认 512
///   - clockSource: 内部时钟源 默认 1
///   - ecgPgaGain: 默认 2
///   - isFilterWave: YES = 算法滤波数据 NO = 原始数据
+(NSData *)PackEcgMeasure:(BOOL)on SampleRate:(uint16_t)sampleRate InnerClockSource:(uint8_t)clockSource EcgPgaGain:(uint8_t)ecgPgaGain DispSrc:(uint8_t)dispSrc
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_FUNCTIN_ECG;
    
  
    bytes[2] = on & 0xFF;
    if (on) {
        // 采样率
        memcpy(bytes+3, (void *)(&sampleRate), sizeof(uint16_t));

        bytes[5] = clockSource;
        bytes[6] = ecgPgaGain;
        
        /*
         bytes[7]:
         0:原始数据
         1:算法库数据
         2:原始数据，并且调用 B-Secur 算法 -- 用神念滤波
         */
//        bytes[7]  = isFilterWave ? 1 : 0;//24-12-23之前 用神念前
        bytes[7]  = dispSrc;//isFilterWave ? 2 : 0; //2024-12-23开始 用神念后
    }
 


    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)PackEcgAndPpgMeasure:(BOOL)on
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_FUNCTIN_ECG_PPG;
    
  
    bytes[2] = on & 0xFF;
    
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)packSettingOxygenMeasure:(NSUInteger)startHor
                           StartMin:(NSUInteger)startMin
                           StartSec:(NSUInteger)startSecond
                             Endhor:(NSUInteger)endHor
                             EndMin:(NSUInteger)endMin
                             EndSec:(NSUInteger)endSec
                           Interval:(NSUInteger)interval IsOn:(BOOL)isOn
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_SET_OXYGEN_MEASURE;
    
    bytes[2] = isOn ? 1 : 0; // 开关
    
    bytes[3] = (uint8_t)startHor;
    bytes[4] = (uint8_t)startMin;
    bytes[5] = (uint8_t)startSecond;
    
    bytes[7] = (uint8_t)endHor;
    bytes[8] = (uint8_t)endMin;
    bytes[9] = (uint8_t)endSec;
    
    *((uint16_t *)(bytes + 11)) = (uint16_t)(interval); //间隔 分钟
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
    
    
}

+(NSData *)packSettingHeartRateMeasurInterval:(NSUInteger)hrInterval SkinTemperatureInterval:(NSUInteger)skinTemperatureInterval IsOn:(BOOL)isOn
{
    
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_SET_HR_TEMP_MEASURE;
    bytes[2] = isOn ? 1 : 0; // 开关
    
    *((uint16_t *)(bytes + 10)) = (uint16_t)hrInterval;
    *((uint16_t *)(bytes + 12)) = (uint16_t)skinTemperatureInterval;
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)packSportMode:(NSUInteger)startHor StartMin:(NSUInteger)startMin
                StartSec:(NSUInteger)startSecond Endhor:(NSUInteger)endHor
                  EndMin:(NSUInteger)endMin EndSec:(NSUInteger)endSec
              HrIntreval:(NSUInteger)hrInterval SkinTemperatureInterval:(NSUInteger)skinTemperatureInterval
                BloodOxygenInterval:(NSUInteger)oxygeninterval
                    IsOn:(BOOL)isOn
{
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_SET_SPORT_MODE;
    bytes[2] = isOn ? 1 : 0; // 开关
    
    bytes[3] = (uint8_t)startHor;
    bytes[4] = (uint8_t)startMin;
    bytes[5] = (uint8_t)startSecond;
    
    
    
    bytes[7] = (uint8_t)endHor;
    bytes[8] = (uint8_t)endMin;
    bytes[9] = (uint8_t)endSec;
    
    *((uint16_t *)(bytes + 11)) = (uint16_t)hrInterval;
    *((uint16_t *)(bytes + 13)) = (uint16_t)oxygeninterval;
    *((uint16_t *)(bytes + 15)) = (uint16_t)skinTemperatureInterval;
    
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
    
}


// 清空设备历史
+(NSData *)packClearHistory {
    
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_CLEAR_HIS_DATA;
    
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}

+(NSData *)packHistoryData {
    
    uint8_t bytes[20] = {0};
    
    // 包头
    bytes[0] = CMD_HEAD;
    
    // 命令字
    bytes[1] = PACK_CMD_HIS_DATA;
    
    // crc
    bytes[INDEX_CRC] = [[self class]crc8:[NSData dataWithBytes:bytes length:DATA_PKG_SIZE]];
    
    return  [NSData dataWithBytes:bytes length:20];
}



/// 解包
/// @param data 蓝牙原始包
-(void)receiveData:(NSData *)data {
    NSUInteger length = data.length;
    
    if (length != 20) {
        return;
    }
    
    uint8_t *dataBytes = (uint8_t *)[data bytes];
    if (dataBytes[0] != CMD_HEAD) {
        return;
    }
    
//    DebugNSLog(@"srpacket recv pack tag :%X", dataBytes[1]);
    
    switch (dataBytes[1]) {
        case DEVICE_RESPONSE_OXYGEN_HRV: // 血氧 hrv上报  0x83
        {
            uint8_t status = dataBytes[6];// 0未测量 1测量中 2数据有效
            
            uint8_t oxygen = dataBytes[2];
            uint8_t heartRate = dataBytes[3];
            NSInteger hrv = *((uint16_t *)(dataBytes + 4));//(dataBytes[4] << 8) & 0XFF + dataBytes[5];
//            DebugNSLog(@"血氧 %d hrv %ld 心率 %d", oxygen, (long)hrv, heartRate);
//            float hrv_f = sqrtf(hrv * 1.0);
//            DebugNSLog(@"实时hrv %d", hrv);
            NSNumber *cbHr, *cbHrv, *cbOxygen;
            cbHrv = @(hrv);
            // 回调血氧
            if (oxygen > 0 ) {
                if (oxygen> 100) {
                    oxygen = 100;
                }
                cbOxygen = @(oxygen);
            }
            // 回调心率
            if (heartRate >0 && heartRate <= 200) {
                cbHr = @(heartRate);
            }
            // 回调hrv
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceRealtimeHRV:BloodOxygen:HeartRate:Status:)] ) {
                [self.dataDelegate stkeyFobServiceRealtimeHRV:cbHrv  BloodOxygen:cbOxygen HeartRate:cbHr Status:status];
            }
            
            
            
        }
            break;
        case DEVICE_RESPONSE_STEP_DATA: // 0X84 计步数据 废弃 协议1.9开始
        {
//            uint16_t steps = *(uint16_t *)(dataBytes + 2);
//            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceRealtimeSteps:)] ) {
//                [self.dataDelegate stkeyFobServiceRealtimeSteps:@(steps)];
//            }
            
        }
            break;
        case DEVICE_RESPONSE_TEMPRETRUE_DATA:   // 0X85 体表温度
        {
            uint16_t temp = *(uint16_t *)(dataBytes + 2);
            
            float callbackTemp = (temp + 200) / 10.0f;
            
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceRealtimeTemperaure:)] ) {
                [self.dataDelegate stkeyFobServiceRealtimeTemperaure:@(callbackTemp)];
            }
        }
            break;
        case DEVICE_RESPONSE_RESPCMD: // 设备收包应答
        {
            uint8_t cmd = dataBytes[2];   // 返回下发命令
            uint8_t excuteRes = dataBytes[4]; // 执行结果, 0 = 正确
            uint8_t reason = dataBytes[5]; // 错误原因
            
            CMD_EXECTE_ERROR_REASON rea = reason;
            
            DebugNSLog(@"device recv cmd  :%X  excute cmd res:%X", cmd, excuteRes);

            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceSendCmdExcute: Succ:Reason:)] ) {
                [self.dataDelegate stkeyFobServiceSendCmdExcute:cmd Succ:excuteRes == 0 Reason:rea];
            }
            
            if (cmd == PACK_CMD_HIS_DATA) { // 无法同步时的 多余超时回调
                [self.hisTimer invalidate];
                self->_isTranslatingHistory = NO;
                self->_historyCount = 0;
            }
            
        }
            break;
        case DEVICE_RESPONSE_BATTERY_LEVEL:
        {
            uint16_t voltage = ((uint16_t *)dataBytes)[1]; // 电压
            uint8_t isCharging = dataBytes[4];
            uint8_t percent = dataBytes[5]; // sr09 新增百分比
            
            // stkeyFobServiceBatteryLevel
            int batteryLevel = 0;
            
            if (percent > 0) {
                batteryLevel = percent;
            } else {
                batteryLevel = [SDKTool toBatteryLevel:voltage IsCharge:isCharging IsWireness:[LTSRingSDK instance].currentDevice.isWirenessCharge.boolValue];
            }
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceBatteryLevel:IsCharging:)] ) {
                [self.dataDelegate stkeyFobServiceBatteryLevel:(NSUInteger)batteryLevel IsCharging:isCharging == 1];
            }
        }
            break;
        case DEVICE_RESPONSE_DEVICEINFO_DATA:// 0X87
        {
            // 设备信息
            
            SRDeviceInfo *info = [[SRDeviceInfo alloc]initWithData:data];
            
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceDeviceInfo:)] ) {
                [self.dataDelegate stkeyFobServiceDeviceInfo:info];
            }
            _projectId = info.projectId; // 项目代号 区分什么设备

        }
            break;
        case DEVICE_RESPONSE_SN_DATA: // sn号 和其他信息 0x88
        {
            NSString *snString;
            NSData * snData;
            uint8_t *snDataBytes;
            
            snData = [data subdataWithRange:NSMakeRange(2, 8)];
            snDataBytes = (uint8_t *)[snData bytes];
            snString = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x", snDataBytes[0],
                        snDataBytes[1],
                        snDataBytes[2],
                        snDataBytes[3],
                        snDataBytes[4],
                        snDataBytes[5],
                        snDataBytes[6],
                        snDataBytes[7]];
            long long snNUmber = [snString longLongValue];
            snString = [NSString stringWithFormat:@"%lld", snNUmber];
           
            
//            NSString *snString = [[NSString alloc] initWithData:snData encoding:NSUTF8StringEncoding];
            
            uint8_t * bytes = (uint8_t *)[data bytes];
            // sos开关
            BOOL isSosOpen = bytes[10] > 0;
            
            UInt8 doubleTapTimes = bytes[11]; // 触发sos的双击次数
            UInt8 singleTapSepTime = bytes[12]; // 两次单击的间隔
            uint8_t tapDetectionThreshold = bytes[13]; //拍击检测阈值
            uint8_t doubleTapEffectStartTime = bytes[14]; // 双击有效起始时间 单位 秒
            uint8_t doubleTapEffectEndTime = bytes[15]; // 双击有效结束时间 单位 秒
            BOOL isBinded = bytes[16] > 0; // 是否绑定

            uint8_t sampleRate = bytes[17];  // 采样率
            uint8_t waveDataSwitch = bytes[18]; // 原始波形上报开关

            
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceSampleRate:WaveSwitch:)] )
            {
                [self.dataDelegate stkeyFobServiceSampleRate:sampleRate WaveSwitch:waveDataSwitch > 0];
            }
            
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceSN: OriginSNData:)] ) {
                [self.dataDelegate stkeyFobServiceSN:snString OriginSNData:snData];
            }
            
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobService:DoubleTapTimes:SingleTapInterval:TapDetectionThreshold:DoubleTapEffectStartTime:DoubleTapEffectEndTime:Isbinded:)] ) {
                [self.dataDelegate stkeyFobService:isSosOpen
                                    DoubleTapTimes:doubleTapTimes
                                 SingleTapInterval:singleTapSepTime
                             TapDetectionThreshold:tapDetectionThreshold
                          DoubleTapEffectStartTime:doubleTapEffectStartTime
                            DoubleTapEffectEndTime:doubleTapEffectEndTime Isbinded:isBinded];
            }
            
        }
            break;
            
        case  DEVICE_RESPONSE_HISTORY_COUNT: // 历史数据个数
        {
            self.isTranslatingHistory = YES;
            // 记录个数
            uint16_t count = ((uint16_t *)dataBytes)[1];
            _historyCount = count;
            DebugNSLog(@"history count %d", count);
            // 启动超时
            [self.hisTimer invalidate];
            __weak typeof(self) weakSelf = self;
            NSTimeInterval interval = 50 * count * 1.0 / 1000; // 每条数据给50毫秒时间
            self.hisTimer = [NSTimer scheduledTimerWithTimeInterval:interval repeats:NO block:^(NSTimer * _Nonnull timer) {
                __strong typeof(weakSelf) strongSelf = weakSelf;
                if (strongSelf.isTranslatingHistory) {
                    if (strongSelf != nil && [strongSelf.dataDelegate respondsToSelector:@selector(stkeyFobServiceHistoryTimeout)] ) {
                        [strongSelf.dataDelegate stkeyFobServiceHistoryTimeout];
                    }
                    strongSelf->_isTranslatingHistory = NO;
                    strongSelf->_historyCount = 0;
                }
                
                
            }];
            
            // 获取历史数据
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceHistoryCount:)] ) {
                [self.dataDelegate stkeyFobServiceHistoryCount:count];
            }
        }
            break;
        case   DEVICE_RESPONSE_HISTORY_DATA: // 历史数据上报 0x82
        {
            // 历史数据
            SRHistoryDataSR03 *hisData_03 =  [[SRHistoryDataSR03 alloc]initWithData:data];
//            SRHistoryData *hisData = [[SRHistoryData alloc] initWithData:data];
            _historyCount = _historyCount - 1;
            if (_historyCount == 0) {
                // 传输完成
                _isTranslatingHistory = NO;
                [self.hisTimer invalidate];
            }
            
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceHistorySR03Data:IsComplete:)] ) {
                [self.dataDelegate stkeyFobServiceHistorySR03Data:hisData_03 IsComplete:_historyCount == 0];
            }
            
            
        }
            break;
        case DEVICE_RESPONSE_SOS: // sos触发
        {
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceSOShappen)] ) {
                [self.dataDelegate stkeyFobServiceSOShappen];
            }
            
            
        }
            break;
        case DEVICE_RESPONSE_HISTORY_DATA_3:
        case DEVICE_RESPONSE_HISTORY_DATA_2: // 历史数据上报 2 2023-7-19 0x91
        {
            // 历史数据
            SRHistoryDataSR03 *hisData_03 =  [[SRHistoryDataSR03 alloc]initWithData:data];
//            SRHistoryData *hisData = [[SRHistoryData alloc] initWithData:data];
            _historyCount = _historyCount - 1;
            if (_historyCount == 0) {
                // 传输完成
                _isTranslatingHistory = NO;
                [self.hisTimer invalidate];
            }

            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceHistorySR03Data:IsComplete:)] ) {
                [self.dataDelegate stkeyFobServiceHistorySR03Data:hisData_03 IsComplete:_historyCount == 0];
            }
        }
            break;
        case DEVICE_RESPONSE_SOS_MEASUREDATA:
        {
            uint8_t * bytes = (uint8_t *)[data bytes];
            float temperature = (bytes[2]  + 200) / 10.0f; // 体温
            NSInteger hr = bytes[3] & 0xff; // 心率
            NSInteger oxygen = bytes[4] & 0xff; // 血氧
            
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceSOSData:HeartRate:BloodOxygen:)] ) {
                [self.dataDelegate stkeyFobServiceSOSData:temperature HeartRate:hr BloodOxygen:oxygen];
            }
        }
            break;
        case DEVICE_RESPONSE_MANUFAT_R1: //上报厂家验证 R1
        {
            NSData *r1Data = [data subdataWithRange:NSMakeRange(2, 16)];
//            uint8_t * bytes = (uint8_t *)[data bytes];
//            uint16_t r1 = 0;
//            memcpy((void *)&r1, bytes+2, sizeof(uint16_t)); // 取出设备发来的的R1
            if([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceAESRecvR1:)])
            {
                [self.dataDelegate stkeyFobServiceAESRecvR1:r1Data];
            }
            
            
        }
            break;
        case DEVICE_RESPONSE_MANUFAT_RES: // 上报厂家验证结果:
        {
            uint8_t * bytes = (uint8_t *)[data bytes];
           
            if([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceAESAuthResult:)])
            {
                BOOL succ = bytes[2] > 0;
                [self.dataDelegate stkeyFobServiceAESAuthResult:succ];
            }
            
        }
            break;
        case DEVICE_RESPONSE_HR_MEASURE_DURATION: //上报 测量时长
        {
            uint8_t * bytes = (uint8_t *)[data bytes];
            
            uint8_t duretuon = bytes[2]; //心率测量时间 单位 秒
            
            uint32_t pd_threshold = *((uint32_t *)(bytes + 3));// pd 采样阈值
            uint32_t pd_range_1 = *((uint32_t *)(bytes + 7)); // pd 采样值波动范围1
            uint32_t pd_range_2 = *((uint32_t *)(bytes + 11)); // pd 采样值波动范围2
            
            DebugNSLog(@"测量时长 %d , pd阈值 %d, 范围1 %d, 范围2 %d", duretuon, pd_threshold, pd_range_1, pd_range_2);
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceHrMeasuDuration:PD_THRESHOLD:PD_RANGE_1:PD_RANGE_2:)]) {
                
                [self.dataDelegate stkeyFobServiceHrMeasuDuration:duretuon PD_THRESHOLD:pd_threshold PD_RANGE_1:pd_range_1 PD_RANGE_2:pd_range_2];
            }
            
            // - (void)stkeyFobServiceOxygenMeasureInterval:(uint16_t)minuteInterval OxygenSwitch:(BOOL)on;
            uint16_t intervalMinute = *((uint16_t *)(bytes + 15));
            BOOL oxygenOn = *((uint8_t *)(bytes + 17));
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceOxygenMeasureInterval:OxygenSwitch:)]) {
                
                [self.dataDelegate stkeyFobServiceOxygenMeasureInterval:intervalMinute OxygenSwitch:oxygenOn];
            }
            

            
        }
            break;
            
        case DEVICE_RESPONSE_Infrared_Data_Sources: //红外源数据上报 0XBB
        {
            uint8_t * bytes = (uint8_t *)[data bytes];
            
            void *dataStart = bytes + 2; // 数据起始位置
            // 8个 uint16
            NSMutableArray<NSData *> *dataArray = [NSMutableArray new];
            
            uint16_t *rep = dataStart;
            
            for (int i = 0; i < 8; i++) {
                uint16_t irShort = *(rep + i);
                // 回调
                if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceIrData:)]) {
                    
                    [self.dataDelegate stkeyFobServiceIrData:irShort];
                }
            }
            
            
        }
            break;
        case DEVICE_RESPONSE_Red_light_source_data: // 红光源数据上报 0xbc
        {
            uint8_t * bytes = (uint8_t *)[data bytes];
            
            void *dataStart = bytes + 2; // 数据起始位置
            // 8个 uint16
            NSMutableArray<NSData *> *dataArray = [NSMutableArray new];
            
            uint16_t *rep = dataStart;
            
            for (int i = 0; i < 8; i++) {
                uint16_t redShort = *(rep + i);
                // 回调
                // 回调
                if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceRedData:)]) {
                    
                    [self.dataDelegate stkeyFobServiceRedData:redShort];
                }
            }
            
        }
            break;
        case DEVICE_RESPONSE_IR_AND_RED_SOURCE: // 0xBD
        {
            uint8_t * bytes = (uint8_t *)[data bytes];
            
            void *dataStart = bytes + 2; // 数据起始位置
            uint16_t *rep = dataStart;
            for (int i = 0; i < 8; i++) {
                uint16_t sourceData = *(rep + i);
                if (i%2 == 0) {
                    
                    if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceIrData:)]) {
                        
                        [self.dataDelegate stkeyFobServiceIrData:sourceData];
                    }
                    
                } else {
                    
                    if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceRedData:)]) {
                        
                        [self.dataDelegate stkeyFobServiceRedData:sourceData];
                    }
                }
                
            }
        }
            break;
        case  DEVICE_RESPONSE_ECG_ROW: //0X94,ecg上报
        {
            uint8_t * bytes = (uint8_t *)[data bytes];
            void * dataStart = bytes+2;
            
            void *countPoint =  bytes+17;
            uint16_t count = *((uint16_t *)countPoint) & 0XFFFF; // 数据计数
            
            NSMutableArray<NSNumber *> *ecgDataArray = [NSMutableArray new];
            for (int i = 0; i < 5; i++) {
                uint8_t *ecgDataStart =  dataStart + i*3;
                
                uint8_t ecg_data[3] = {0};
                
                
                uint8_t data1 = *ecgDataStart & 0xFF;
                uint8_t data2 = *(ecgDataStart+1) ;
                uint8_t data3 = *(ecgDataStart+2) ;
                
                ecg_data[0] = data3;
                ecg_data[1] = data2;
                ecg_data[2] = data1;
                
                int32_t int32_ecg_data = 0;
                 if(ecg_data[0] & 0x02){//negative
                    int32_ecg_data = (int32_t)((ecg_data[0]<<16) + (ecg_data[1]<<8) +  ecg_data[2]) - 0x40000; //change to int32_t
                 }
                 else{
                     int32_ecg_data = (int32_t)((ecg_data[0]<<16) + (ecg_data[1]<<8) +  ecg_data[2]);
                 }

//                uint32_t ecgData =  (data1 << 16) + (data2<<8) + data3;
                [ecgDataArray addObject:@(int32_ecg_data)];
            }
            
            SrEcgData *ecgObj = [[SrEcgData alloc]init];
            ecgObj.type = SRECG_TYPE_ONLY_ECG;
            ecgObj.ecgArray = ecgDataArray;
            ecgObj.idx = count;
            // 回调
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceEcg:)]) {
                
                [self.dataDelegate stkeyFobServiceEcg:ecgObj];
            }
            
        }
            break;
        case  DEVICE_RESPONSE_ECG_PPG_ROW:        // 0X95 ecg+ppg上报
        {
            uint8_t * bytes = (uint8_t *)[data bytes];
            void * dataStart = bytes+2;
            
            void *countPoint =  bytes+17;
            uint16_t count = *((uint16_t *)countPoint) & 0XFFFF; // 数据计数
            
            NSMutableArray<NSNumber *> *ecgDataArray = [NSMutableArray new];
            NSMutableArray<NSNumber *> *ppgDataArray = [NSMutableArray new];

            for (int i = 0; i < 3; i++) {
                uint8_t *ecgDataStart =  dataStart + i*5;
                
                uint8_t ppgdata1 = *ecgDataStart & 0xFF;
                uint8_t ppgdata2 = *(ecgDataStart+1) & 0xFF;
                uint8_t ppgdata3 = ((*(ecgDataStart+2) & 0xFF) >> 4) & 0xFF;
                
                int ppgData =  (ppgdata1 << 12) + (ppgdata2<<4) + ppgdata3;
                [ppgDataArray addObject:@(ppgData)];
                
                uint32_t ecgdata1 = (*(ecgDataStart+2) & 0x01) << 16;
                uint8_t ecgdata2 = *(ecgDataStart+3) & 0xFF;
                uint8_t ecgdata3 = *(ecgDataStart+4) & 0xFF;
                
                uint32_t ecg = ecgdata1 + (ecgdata2<<8)&0XFFFF + ecgdata3;
                [ecgDataArray addObject:@(ecg)];
            }
            
            SrEcgData *ecgPpgObj = [[SrEcgData alloc]init];
            ecgPpgObj.type = SRECG_TYPE_ECG_PPG;
            ecgPpgObj.ecgArray = ecgDataArray;
            ecgPpgObj.ppgArray = ppgDataArray;
            ecgPpgObj.idx = count;
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceEcgAndPPg:)]) {
                
                [self.dataDelegate stkeyFobServiceEcgAndPPg:ecgPpgObj];
            }
            
        }
            break;
        case  DEVICE_RESPONSE_ECG_PPG_FILTER: // 0x96 ecg算法波形上报
        {
            uint8_t * bytes = (uint8_t *)[data bytes];
            void * dataStart = bytes+2;
            
            void *countPoint =  bytes+16;
            uint16_t count = *((uint16_t *)countPoint) & 0XFFFF; // 数据计数
            
            NSMutableArray<NSNumber *> *ecgDataArray = [NSMutableArray new];
            for (int i = 0; i < 7; i++) {
                uint8_t *ecgDataStart =  dataStart + i*2;
                
                int16_t ecgData =  *((int16_t *)ecgDataStart);
                
//                uint8_t data1 = *ecgDataStart & 0xFF;
//                uint8_t data2 = *(ecgDataStart+1) & 0xFF;
//
//
//                uint32_t ecgData =  (data1 << 8) + data2;
                int16_t lowCase = ntohs(ecgData); // 转小端
                [ecgDataArray addObject:@(lowCase)];
            }
            
            SrEcgData *ecgObj = [[SrEcgData alloc]init];
            ecgObj.type = SRECG_TYPE_ONLY_ECG;
            ecgObj.ecgArray = ecgDataArray;
            ecgObj.idx = count;
            ecgObj.isAlgorithData = YES; //标记是算法数据
            
            // 回调
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceEcg:)]) {
                
                [self.dataDelegate stkeyFobServiceEcg:ecgObj];
            }
            
        }
            break;
       
        case  DEVICE_RESPONSE_ECG_RESULT: // ecg算法计算结果
        {
            SrEcgAlgorithmResults *result = [[SrEcgAlgorithmResults alloc]initWithData:data];
            
            // 回调
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceEcgResult:)]) {
                
                [self.dataDelegate stkeyFobServiceEcgResult:result];
            }
            
        }
            break;
        case DEVICE_RESPONSE_ECG_LEAD_ON:
        {
            uint8_t * bytes = (uint8_t *)[data bytes];
            BOOL lead_on = bytes[2];
            if ([self.dataDelegate respondsToSelector:@selector(stkeyFobServiceEcgLeadOn:)]) {
                [self.dataDelegate stkeyFobServiceEcgLeadOn:lead_on];
            }
        }
            break;
        default:
            break;
    }
    
}



#pragma mark --crc
// crc校验计算
+(uint8_t)crc8:(NSData *)packData {
    uint8_t crc = 0;
    Byte * bytes = (Byte *)[packData bytes];
    
    for (int i = 0; i < packData.length; i++) {
        crc = crc ^ (bytes[i]);
//        crc = crc & 0xffff;
    }
//    DebugNSLog(@"srpacket crc8 bytes[1] = %X", bytes[1]);
    return crc;
}

// crc校验检查
+(BOOL)crc8Checker:(NSData *) packData {
    if (YES) {
//        NSLog(@"CCL crc8Checker crc on");
        if (!( packData != nil && packData.length == DATA_PKG_SIZE) ) {
            return NO;
        }
        Byte * dataBytes = (Byte *)[packData bytes];
        if (dataBytes[INDEX_PKG_HEAD] == CMD_HEAD)
        {
            return  [self crc8:packData] == (dataBytes[INDEX_CRC] & 0xff);
        } else {
            return NO;
        }
    } else {
//        NSLog(@"CCL crc8Checker crc off");
        return true;
    }
}

@end
